コンポーネントを Flux フロで管理したいならuseState
の代わりに使うのがいいかもしれません。特に管理する状態が多い場合はこちらを使うと処理を外部に切り分けられコードが見やすくなるのでお勧めします。
このフックは2-3の引数を受け取ります。1つ目は Reducer、2つ目はその Reducer の初期値、3つ目はオプショナルで2つ目の初期値が複雑な場合、それを更に弄る為の関数です。このフックは戻り位置に状態state
とdispatch
という Reducer へアクションを流すための関数を返します。
例です。
const init = initialState => {
initialState.count = Math.floor(Math.random() * 10);
return initialState;
};
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";
const initialCountState = { count: 0 };
const countReducer = (state, action) => {
switch (action.type) {
case INCREMENT: {
const nextState = { ...state };
nextState.count++;
return nextState;
}
case DECREMENT: {
const nextState = { ...state };
nextState.count--;
return nextState;
}
default: {
return state;
}
}
};
const App = () => {
const [state, dispatch] = useReducer(countReducer, initialCountState, init);
const increment = useCallback(() => {
dispatch({
type: INCREMENT
});
}, [dispatch]);
const decrement = useCallback(() => {
dispatch({
type: DECREMENT
});
}, [dispatch]);
return (
{state.count}
);
};
useReducer
には上記の説明のように(ここでは無理やり)3つの引数を渡してます。initialState
ではcount
は0
としてますが、init
関数により0
から9
のどれかに書き換えられます。
アクションを発行する関数はuseCallback
で囲みます。この Reducer を使った更新ではdispatch
関数は毎回変更が入ってしまい毎回アクション関数を新しく作ることになってしまいますが、依存しないprops
の更新が来た時などにはそれを防げる為です。今回はprops
がありませんが、そういった場合でも癖として常にやっておいたほうがいいかなと思います。
<button>
をクリックするとcountReducer
へアクションが飛びます。countReducer
ではそのアクションのtype
を見て捌きます。switch
構文で捌くことが多いですが、if
構文などでも構いません。
そしてcountReducer
の戻り値が次のuseReducer
の戻り値のstate
へやってきます。そして、その値でコンポーネントが再描画される…という動作を繰り返します。